package net.lesscoding.rpc.handler;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import net.lesscoding.rpc.message.RpcRequestMessage;
import net.lesscoding.rpc.message.RpcResponseMessage;
import net.lesscoding.rpc.service.HelloService;
import net.lesscoding.rpc.service.ServiceFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author eleven
 * @date 2024/12/4 8:32
 * @apiNote
 */
@Slf4j
@ChannelHandler.Sharable
public class RpcRequestMessageHandler extends SimpleChannelInboundHandler<RpcRequestMessage> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequestMessage msg) throws Exception {
        log.info("接收到客户端的请求：{}", msg);
        RpcResponseMessage response = new RpcResponseMessage();
        response.setSequenceId(msg.getSequenceId());
        try {
            // 反射调用
            Object service = ServiceFactory.getService(Class.forName(msg.getInterfaceName()));
            Method method = service.getClass()
                    .getMethod(msg.getMethodName(), msg.getParamsType());
            Object invoke = method.invoke(service, msg.getParams());
            response.setReturnValue(invoke);
        } catch (Exception e) {
            e.printStackTrace();
            response.setExceptionValue(new Exception("远程调用出错" + e.getCause().getMessage()));
        }
         ctx.writeAndFlush(response);

    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        RpcRequestMessage msg = new RpcRequestMessage(
                1,
                "net.lesscoding.rpc.service.HelloService",
                "sayHello",
                String.class,
                new Class[]{String.class},
                new Object[]{"张三"}
        );
        // 反射调用
        HelloService helloService = (HelloService) ServiceFactory.getService(Class.forName(msg.getInterfaceName()));
        Method method = helloService.getClass()
                .getMethod(msg.getMethodName(), msg.getParamsType());
        System.out.println(method.invoke(helloService, msg.getParams()));
    }
}
